{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 13.2 Creating Model Descriptions with Patsy（利用Patsy创建模型描述）\n",
    "\n",
    "Patsy是一个python库，用于描述统计模型（尤其是线性模型），方法是通过一个叫做公式语法（formula syntax）的字符串来描述。这种公式语法的灵感来源于R和S语言中的公式语法。\n",
    "\n",
    "Patsy的公式是有特殊格式的字符串，像下面这样：\n",
    "\n",
    "    y ~ x0 + x1\n",
    "    \n",
    "这种a + b的语法并不代表将a和b相加，而是代表为模型创建的设计矩阵的术语（terms in the design matrix）。patsy.dmatrices函数，取一个公式字符串和一个数据集（可以使DataFrame或dict），然后为线性模型产生设计矩阵："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "data = pd.DataFrame({'x0': [1, 2, 3, 4, 5],\n",
    "                     'x1': [0.01, -0.01, 0.25, -4.1, 0.], \n",
    "                     'y': [-1.5, 0., 3.6, 1.3, -2.]})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>x0</th>\n",
       "      <th>x1</th>\n",
       "      <th>y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0.01</td>\n",
       "      <td>-1.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>-0.01</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>0.25</td>\n",
       "      <td>3.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>-4.10</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0.00</td>\n",
       "      <td>-2.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   x0    x1    y\n",
       "0   1  0.01 -1.5\n",
       "1   2 -0.01  0.0\n",
       "2   3  0.25  3.6\n",
       "3   4 -4.10  1.3\n",
       "4   5  0.00 -2.0"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import patsy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "y, X = patsy.dmatrices('y ~ x0 + x1', data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们得到："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 1)\n",
       "     y\n",
       "  -1.5\n",
       "   0.0\n",
       "   3.6\n",
       "   1.3\n",
       "  -2.0\n",
       "  Terms:\n",
       "    'y' (column 0)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 3)\n",
       "  Intercept  x0     x1\n",
       "          1   1   0.01\n",
       "          1   2  -0.01\n",
       "          1   3   0.25\n",
       "          1   4  -4.10\n",
       "          1   5   0.00\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'x0' (column 1)\n",
       "    'x1' (column 2)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这些Patsy DesignMatrix实例是Numpy的ndarrays，附有额外的元数据（metadata）:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.5],\n",
       "       [ 0. ],\n",
       "       [ 3.6],\n",
       "       [ 1.3],\n",
       "       [-2. ]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.asarray(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.  ,  1.  ,  0.01],\n",
       "       [ 1.  ,  2.  , -0.01],\n",
       "       [ 1.  ,  3.  ,  0.25],\n",
       "       [ 1.  ,  4.  , -4.1 ],\n",
       "       [ 1.  ,  5.  ,  0.  ]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.asarray(X)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们可能奇怪X中的Intercept是从哪里来的。这其实是线性模型的一个惯例，比如普通最小二乘回归法（ordinary least squares regression）。我们可以去掉这个截距（intercept），通过加添术语`+0`给模型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 2)\n",
       "  x0     x1\n",
       "   1   0.01\n",
       "   2  -0.01\n",
       "   3   0.25\n",
       "   4  -4.10\n",
       "   5   0.00\n",
       "  Terms:\n",
       "    'x0' (column 0)\n",
       "    'x1' (column 1)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "patsy.dmatrices('y ~ x0 + x1 + 0', data)[1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这种Patsy对象可以直接传入一个算法，比如numpy.linalg.lstsq，来进行普通最小二乘回归的计算："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "coef, resid, _, _ = np.linalg.lstsq(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.31290976],\n",
       "       [-0.07910564],\n",
       "       [-0.26546384]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "coef"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Intercept    0.312910\n",
       "x0          -0.079106\n",
       "x1          -0.265464\n",
       "dtype: float64"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "coef = pd.Series(coef.squeeze(), index=X.design_info.column_names)\n",
    "coef"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1 Data Transformations in Patsy Formulas（Patsy公式的数据变换）\n",
    "\n",
    "我们可以把python和Patsy公式混合起来。当评估公式的时候，库会尝试找到封闭域中的公式："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "y, X = patsy.dmatrices('y ~ x0 + np.log(np.abs(x1) + 1)', data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 3)\n",
       "  Intercept  x0  np.log(np.abs(x1) + 1)\n",
       "          1   1                 0.00995\n",
       "          1   2                 0.00995\n",
       "          1   3                 0.22314\n",
       "          1   4                 1.62924\n",
       "          1   5                 0.00000\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'x0' (column 1)\n",
       "    'np.log(np.abs(x1) + 1)' (column 2)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一些常用的变量变换，包括标准化（standardizing (平均值0，方差1）和中心化（减去平均值）。Patsy有内建的函数可以做到这些："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "y, X = patsy.dmatrices('y ~ standardize(x0) + center(x1)', data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 3)\n",
       "  Intercept  standardize(x0)  center(x1)\n",
       "          1         -1.41421        0.78\n",
       "          1         -0.70711        0.76\n",
       "          1          0.00000        1.02\n",
       "          1          0.70711       -3.33\n",
       "          1          1.41421        0.77\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'standardize(x0)' (column 1)\n",
       "    'center(x1)' (column 2)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "作为建模的一部分，我们可能会在一个数据及上训练模型，然后在另一个数据及上评价模型。当使用中心化或标准化这样的转换时，我们必须注意，必须用模型在新数据集上做预测。这叫做状态变换（stateful transformations）。因为我们必须用原本在训练集上得到的平均值和标准差，用在新的数据集上。\n",
    "\n",
    "通过保存原先数据集中的信息，patsy.build_design_matrices函数能把变换用在新的数据集上："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "new_data = pd.DataFrame({\n",
    "        'x0': [6, 7, 8, 9], \n",
    "        'x1': [3.1, -0.5, 0, 2.3],\n",
    "        'y': [1, 2, 3, 4]})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[DesignMatrix with shape (4, 3)\n",
       "   Intercept  standardize(x0)  center(x1)\n",
       "           1          2.12132        3.87\n",
       "           1          2.82843        0.27\n",
       "           1          3.53553        0.77\n",
       "           1          4.24264        3.07\n",
       "   Terms:\n",
       "     'Intercept' (column 0)\n",
       "     'standardize(x0)' (column 1)\n",
       "     'center(x1)' (column 2)]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_X = patsy.build_design_matrices([X.design_info], new_data)\n",
    "new_X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "因为加号在Patsy公式中不代表加法，如果想要把两个列通过名字相加，必须把他们用I函数包起来："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 2)\n",
       "  Intercept  I(x0 + x1)\n",
       "          1        1.01\n",
       "          1        1.99\n",
       "          1        3.25\n",
       "          1       -0.10\n",
       "          1        5.00\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'I(x0 + x1)' (column 1)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y, X = patsy.dmatrices('y ~ I(x0 + x1)', data)\n",
    "X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Patsy有一些其他的内建转换，得来patsy.builtins模块里。更多的信息请参考文档。\n",
    "\n",
    "Categorical数据有特殊的类用于变换，下面进行介绍。\n",
    "\n",
    "# 2 Categorical Data and Patsy（Categorical数据和Patsy）\n",
    "\n",
    "非数值型数据可以通过很多种方式变为一个模型设计矩阵。这个话题很大，这里只做简单介绍。\n",
    "\n",
    "当我们在Patsy公式中使用非数值术语时，这些类型数据默认会被转换为哑变量。如果有截距，一个层级上的截距会被舍弃，防止出现共线性："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "data = pd.DataFrame({'key1': ['a', 'a', 'b', 'b', 'a', 'b', 'a', 'b'], \n",
    "                     'key2': [0, 1, 0, 1, 0, 1, 0, 0], \n",
    "                     'v1': [1, 2, 3, 4, 5, 6, 7, 8],\n",
    "                     'v2': [-1, 0, 2.5, -0.5, 4.0, -1.2, 0.2, -1.7] })"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (8, 2)\n",
       "  Intercept  key1[T.b]\n",
       "          1          0\n",
       "          1          0\n",
       "          1          1\n",
       "          1          1\n",
       "          1          0\n",
       "          1          1\n",
       "          1          0\n",
       "          1          1\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'key1' (column 1)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y, X = patsy.dmatrices('v2 ~ key1', data)\n",
    "X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果从模型中舍弃截距，每个类型的列会被包含在模型设计矩阵中："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (8, 2)\n",
       "  key1[a]  key1[b]\n",
       "        1        0\n",
       "        1        0\n",
       "        0        1\n",
       "        0        1\n",
       "        1        0\n",
       "        0        1\n",
       "        1        0\n",
       "        0        1\n",
       "  Terms:\n",
       "    'key1' (columns 0:2)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y, X = patsy.dmatrices('v2 ~ key1 + 0', data)\n",
    "X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数值型列可以通过C函数，变为类型列："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (8, 2)\n",
       "  Intercept  C(key2)[T.1]\n",
       "          1             0\n",
       "          1             1\n",
       "          1             0\n",
       "          1             1\n",
       "          1             0\n",
       "          1             1\n",
       "          1             0\n",
       "          1             0\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'C(key2)' (column 1)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y, X = patsy.dmatrices('v2 ~ C(key2)', data)\n",
    "X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当我们在一个模型中使用多个类型术语时，会变得更复杂一些，之前用`key1:key2`的形式来包含有交集的术语，这种方法可以用于使用多个术语，例如，一个方法分析模型（analysis of variance (ANOVA) models）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>key1</th>\n",
       "      <th>key2</th>\n",
       "      <th>v1</th>\n",
       "      <th>v2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>a</td>\n",
       "      <td>zero</td>\n",
       "      <td>1</td>\n",
       "      <td>-1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>a</td>\n",
       "      <td>one</td>\n",
       "      <td>2</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>b</td>\n",
       "      <td>zero</td>\n",
       "      <td>3</td>\n",
       "      <td>2.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>b</td>\n",
       "      <td>one</td>\n",
       "      <td>4</td>\n",
       "      <td>-0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>a</td>\n",
       "      <td>zero</td>\n",
       "      <td>5</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>b</td>\n",
       "      <td>one</td>\n",
       "      <td>6</td>\n",
       "      <td>-1.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>a</td>\n",
       "      <td>zero</td>\n",
       "      <td>7</td>\n",
       "      <td>0.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>b</td>\n",
       "      <td>zero</td>\n",
       "      <td>8</td>\n",
       "      <td>-1.7</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  key1  key2  v1   v2\n",
       "0    a  zero   1 -1.0\n",
       "1    a   one   2  0.0\n",
       "2    b  zero   3  2.5\n",
       "3    b   one   4 -0.5\n",
       "4    a  zero   5  4.0\n",
       "5    b   one   6 -1.2\n",
       "6    a  zero   7  0.2\n",
       "7    b  zero   8 -1.7"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data['key2'] = data['key2'].map({0: 'zero', 1: 'one'})\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (8, 3)\n",
       "  Intercept  key1[T.b]  key2[T.zero]\n",
       "          1          0             1\n",
       "          1          0             0\n",
       "          1          1             1\n",
       "          1          1             0\n",
       "          1          0             1\n",
       "          1          1             0\n",
       "          1          0             1\n",
       "          1          1             1\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'key1' (column 1)\n",
       "    'key2' (column 2)"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y, X = patsy.dmatrices('v2 ~ key1 + key2', data)\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (8, 4)\n",
       "  Intercept  key1[T.b]  key2[T.zero]  key1[T.b]:key2[T.zero]\n",
       "          1          0             1                       0\n",
       "          1          0             0                       0\n",
       "          1          1             1                       1\n",
       "          1          1             0                       0\n",
       "          1          0             1                       0\n",
       "          1          1             0                       0\n",
       "          1          0             1                       0\n",
       "          1          1             1                       1\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'key1' (column 1)\n",
       "    'key2' (column 2)\n",
       "    'key1:key2' (column 3)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y, X = patsy.dmatrices('v2 ~ key1 + key2 + key1:key2', data)\n",
    "X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Patsy还提供一些其他转换类型数据的方案，包括按特定顺序来变换。具体的可以查看文档。"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [py35]",
   "language": "python",
   "name": "Python [py35]"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
